home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 1995 October / Amiga-CD 1995 #10.iso / amiga-magazin / farbdithering / listing3 < prev    next >
Text File  |  1995-08-30  |  3KB  |  87 lines

  1. void DitherFSLevels(Picture *Pict,LONG Levels)
  2. {
  3.   WORD *temp,*this,*next,*swap;
  4.   LONG x,y,v,r,pixel,index;
  5.   LONG range;
  6.  
  7.   // Die Anzahl der Graustufen um 1 vermindern
  8.   Levels--;
  9.  
  10.   // Dieser Bruchwert wird gleich zum Runden verwendet
  11.   range = 255 / Levels;
  12.  
  13.   // Zwischenspeicher beschaffen
  14.   if(temp = (WORD *)AllocVec(sizeof(WORD)*2 *
  15.                          (1 + Pict -> Width + 1)),MEMF_ANY))
  16.   {
  17.     memset(temp,0,sizeof(WORD) * 2 * (1 + Pict -> Width + 1)));
  18.     // Die beiden Zeilenpuffer werden initialisiert
  19.     this = &temp[1]; next = &temp[1 + (1 + Pict -> Width + 1)];
  20.  
  21.     for(y = 0 ; y < Pict -> Height ; y++)
  22.     { // In Zeilen mit ungerader Nummer von rechts nach links
  23.       if(y & 1)
  24.       { for(x = Pict -> Width - 1 ; x >= 0 ; x--)
  25.         { // Position des Pixels bestimmen
  26.           index = x + y * Pict -> Width;
  27.  
  28.           // Helligkeitswert berechnen (0 = Min, 255 = Max)
  29.           v = (Pict -> Red[index] + Pict -> Green[index] +
  30.                Pict -> Blue[index]) / 3;
  31.           v = this[x] + v; // Fehlerwert aufschlagen
  32.  
  33.           // Der Helligkeitswert wird auf den zulässigen
  34.           // Bereich beschränkt
  35.           if(v > 255) pixel = 255;
  36.           else
  37.           { if(v < 0) pixel = 0;
  38.             else      pixel = v;
  39.           }
  40.  
  41.           // Die Helligkeit des Pixels wird abgerundet
  42.           pixel = (pixel / range) * range;
  43.  
  44.           // Der "Fehler" ist die Differenz zwischen dem
  45.           // berechneten Pixelwert und dem zu zeichnenden
  46.           r = v - pixel;
  47.           this[x - 1] += (7 * r) / 16;
  48.           next[x + 1] += (3 * r) / 16;
  49.           next[x    ] += (5 * r) / 16;
  50.           next[x - 1] += (    r) / 16;
  51.  
  52.           SetAPen(RPort,pixel); WritePixel(RPort,x,y);
  53.         }
  54.       }
  55.       else
  56.       { // In Zeilen mit gerader Nummer von links nach rechts
  57.         for(x = 0 ; x < Pict -> Width ; x++)
  58.         { index = x + y * Pict -> Width;
  59.           v = (Pict -> Red[index] + Pict -> Green[index] +
  60.                Pict -> Blue[index]) / 3;
  61.           v = this[x] + v;
  62.  
  63.           if(v > 255) pixel = 255;
  64.           else
  65.           { if(v < 0) pixel = 0;
  66.             else      pixel = (v / range) * range;
  67.           }
  68.  
  69.           r = v - pixel;
  70.           this[x + 1] += (7 * r) / 16;
  71.           next[x - 1] += (3 * r) / 16;
  72.           next[x    ] += (5 * r) / 16;
  73.           next[x + 1] += (    r) / 16;
  74.  
  75.           SetAPen(RPort,pixel); WritePixel(RPort,x,y);
  76.         }
  77.       }
  78.       // Der Inhalt der folgenden in die aktuelle Zeile schieben
  79.       swap = this; this = next; next = swap;
  80.  
  81.       // Die folgende Zeile wird gelöscht
  82.       memset(next,0,sizeof(WORD) * Pict -> Width);
  83.     }
  84.     FreeVec(temp);
  85.   }
  86. }
  87.